package com.pizza.database;

import com.pizza.abstrait.*;
import com.pizza.database.mapping.*;
import com.pizza.model.*;

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.sql.*;
import java.util.*;

/**
 * Class PizzaManager, serveur RMI à exécuter.
 *
 */
public class PizzaManager implements IPizzaManager
{
	private DBConnection dbConnexion;

	public PizzaManager()
	{
		dbConnexion = new DBConnection();
	}

	/*
	 * Méthodes du serveur accessibles par le client pour la gestion d'un CLIENT
	 */
	public boolean createClientDB(Client _client)
	{
		return (new ClientDB(dbConnexion).insertClient(_client) == 1);
	}

	public boolean updateClientDB(AbstractClient _client)
	{
		return (new ClientDB(dbConnexion).updateClient(_client) > 0);
	}

	public Client getClientByMail(String _mail)
	{
		return new ClientDB(dbConnexion).getClientByMail(_mail);
	}

	public List<AbstractAdresse> getListAdressesLivraison(AbstractClient _client)
	{
		return (new AdresseDB(dbConnexion).getListAdressesLivraison(_client));
	}

	public boolean addAdresse(AbstractClient _client, AbstractAdresse _adresse)
	{
		Adresse adresse = new Adresse(_adresse);
		return (new AdresseDB(dbConnexion).insertAdresseLivraison(_client, adresse) == 1);
	}

	public boolean removeAdresse(AbstractClient _client, AbstractAdresse _adresse)
	{
		if (!_client.getAdresseFacturation().equals(_adresse))
			return (new AdresseDB(dbConnexion).removeAdresseLivraison(_client, _adresse) == 1);
		return false;
	}

	/*
	 * Méthodes du serveur accessibles par le client pour la gestion d'une
	 * COMMANDE
	 */
	public boolean createCommandeDB(Commande _commande) throws RemoteException
	{
		return (new CommandeDB(dbConnexion).insertCommande(_commande) == 1);
	}

	public int createPizzasPerso(Pizza _pizza) throws RemoteException
	{
		return new PizzaDB(dbConnexion).insertPizza(_pizza);
	}
	
	public Commande getCommandeById(int _id) throws RemoteException
	{
		return (new CommandeDB(dbConnexion).getCommandeById(_id));
	}

	public ArrayList<Ingredient> getListTousLesIngredients() throws RemoteException
	{
		ArrayList<Ingredient> retour = new ArrayList<Ingredient>();
		IngredientDB ingreDB = new IngredientDB(dbConnexion);
		StringBuilder query = new StringBuilder();
		query.append("SELECT id");
		query.append(" FROM ingredients");

		try
		{
			Statement statement = dbConnexion.getConnection().createStatement();
			ResultSet rs = statement.executeQuery(query.toString());

			while (rs.next())
				retour.add(ingreDB.getIngredientById(rs.getInt("id")));

			statement.close();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}

		return retour;
	}
	
	public ArrayList<AbstractArticle> getListTousLesArticles() throws RemoteException
	{
		ArrayList<AbstractArticle> retour = new ArrayList<AbstractArticle>();
		ArticleDB articleDB = new ArticleDB(dbConnexion);
		StringBuilder query = new StringBuilder();
		query.append("SELECT id");
		query.append(" FROM articles");

		try
		{
			Statement statement = dbConnexion.getConnection().createStatement();
			ResultSet rs = statement.executeQuery(query.toString());

			while (rs.next())
				retour.add(articleDB.getArticleById(rs.getInt("id")));

			statement.close();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}

		return retour;
	}

	public ArrayList<AbstractArticle> getListArticlesBoissons() throws RemoteException
	{
		ArrayList<AbstractArticle> retour = new ArrayList<AbstractArticle>();
		ArticleDB articleDB = new ArticleDB(dbConnexion);
		StringBuilder query = new StringBuilder();
		query.append("SELECT id");
		query.append(" FROM articles WHERE type = 'B'");

		try
		{
			Statement statement = dbConnexion.getConnection().createStatement();
			ResultSet rs = statement.executeQuery(query.toString());

			while (rs.next())
				retour.add(articleDB.getArticleById(rs.getInt("id")));

			statement.close();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}

		return retour;
	}

	public ArrayList<AbstractArticle> getListArticlesDesserts() throws RemoteException
	{
		ArrayList<AbstractArticle> retour = new ArrayList<AbstractArticle>();
		ArticleDB articleDB = new ArticleDB(dbConnexion);
		StringBuilder query = new StringBuilder();
		query.append("SELECT id");
		query.append(" FROM articles WHERE type = 'D'");

		try
		{
			Statement statement = dbConnexion.getConnection().createStatement();
			ResultSet rs = statement.executeQuery(query.toString());

			while (rs.next())
				retour.add(articleDB.getArticleById(rs.getInt("id")));

			statement.close();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}

		return retour;
	}

	public ArrayList<AbstractPizza> getListPizzas() throws RemoteException
	{
		ArrayList<AbstractPizza> retour = new ArrayList<AbstractPizza>();
		PizzaDB pizzaDB = new PizzaDB(dbConnexion);
		StringBuilder query = new StringBuilder();
		query.append("SELECT id");
		query.append(" FROM pizzas WHERE id_clients = 0");

		try
		{
			Statement statement = dbConnexion.getConnection().createStatement();
			ResultSet rs = statement.executeQuery(query.toString());

			while (rs.next())
				retour.add(pizzaDB.getPizzaById(rs.getInt("id")));

			statement.close();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}

		return retour;
	}

	public ArrayList<AbstractPizza> getListPizzasPersos(AbstractClient client)
			throws RemoteException
	{
		ArrayList<AbstractPizza> retour = new ArrayList<AbstractPizza>();
		PizzaDB pizzaDB = new PizzaDB(dbConnexion);
		StringBuilder query = new StringBuilder();
		query.append("SELECT id");
		query.append(" FROM pizzas WHERE id_clients = ");
		if (client != null)
			query.append(client.getId());
		else
			query.append("-1");
		//System.out.println("recup liste pizzas perso"+query);
		//les mettres dans l'ordre du nombre commandé et les 5 premieres uniquement
		//query.append("ORDER BY count LIMIT 5");
		
		try
		{
			Statement statement = dbConnexion.getConnection().createStatement();
			ResultSet rs = statement.executeQuery(query.toString());

			while (rs.next())
				retour.add(pizzaDB.getPizzaById(rs.getInt("id")));

			statement.close();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}

		return retour;
	}

	public ArrayList<AbstractCommande> getListCommandesClient(AbstractClient client)
	throws RemoteException
	{
		ArrayList<AbstractCommande> retour = new ArrayList<AbstractCommande>();
		CommandeDB commandeDB = new CommandeDB(dbConnexion);
		StringBuilder query = new StringBuilder();
		query.append("SELECT id");
		query.append(" FROM commandes WHERE id_clients = ");
		if (client != null)
			query.append(client.getId());
		else
			query.append("-1");
		query.append(" ORDER BY date DESC LIMIT 3 ");
		try
		{
			Statement statement = dbConnexion.getConnection().createStatement();
			ResultSet rs = statement.executeQuery(query.toString());

			while (rs.next())
				retour.add(commandeDB.getCommandeById(rs.getInt("id")));
			statement.close();
		} catch (SQLException e)
		{
			e.printStackTrace();
		}

		return retour;
	
	}
	
	/*
	 * Main pour le demarrage du serveur RMI
	 */
	public static void main(String[] args)
	{
		System.out.println("PizzaManager serveur demarre");

		PizzaManager obj = null;
		IPizzaManager stub = null;
		Registry registry = null;

		// System.out.println("Mise en place du Security Manager ...");
		// System.setSecurityManager(new java.rmi.RMISecurityManager());
		try
		{
			obj = new PizzaManager();
			stub = (IPizzaManager) UnicastRemoteObject.exportObject(obj, 0);
		} catch (Exception e)
		{
			System.err.println("Exception Unicast: " + e.toString());
			e.printStackTrace();
		}

		try
		{
			registry = LocateRegistry.createRegistry(1099);
			// attention, si le registry ne se lance pas
			// assez vite, risque de plantage
			registry = LocateRegistry.getRegistry(1099);
		} catch (Exception e)
		{
			System.err.println("Serveur exception createRegistry: " + e.toString());
			e.printStackTrace();
		}

		try
		{
			registry.rebind("pizzamanager", stub);

			System.out.println("PizzaManager Serveur pret");
		} catch (Exception e)
		{
			System.err.println("PizzaManager Serveur exception rebind: " + e.toString());
			e.printStackTrace();
		}
	}
	
	
}
